#pragma once

#include "Term.hpp"

namespace terms {
	/**
	 * \brief Marker interface to mark atomic terms. 
	 *
	 * Atomic terms are terms that cannot be further
	 * decomposed into subterms.
	 *
	 * Note: Does not inherit from terms::Term itself.
	 **/
	class Atom {	
	public:
		/**
		 * \brief Test, if a term is atomic.
		 *
		 * \returns true, if the term is an Atom, false if it is
		 * a compound term.
		 **/
		virtual bool
		is_atomic() const
		{
			return true;
		}
	};

	/**
	 * \brief Test, if a Term is atomic.
	 *
	 * Simply Calls the Term's is_atomic() method.
	 **/
	template <class Term>
	bool
	is_atomic(const Term &term)
	{
		return term.is_atomic();
	}

	/**
	 * \brief Test, if an Atom is atom (true).
	 *
	 * Specialization that avoid the virtual function call if the
	 * static term type is known to be derived from Atom.
	 **/
	template<>
	bool inline is_atomic<Atom>(const Atom &term);
}
